<template>
  <div :class="['geek-list', !isPadding && 'no-padding']">
    <van-list
      v-model:loading="loading"
      v-model:error="loadError"
      :finished="finished"
      :immediate-check="false"
      offset="100"
      :loading-text="loadText.loadingText"
      :finished-text="loadText.finishedText"
      :error-text="loadText.errorText"
      @load="onLoad">
      <slot></slot>
      <!-- 自定义暂无数据展示效果 -->
      <template
        v-if="loadText.finishedText === loadText.noData"
        #finished>
        <no-data />
      </template>
    </van-list>
  </div>
</template>

<script lang="ts" setup>
import api from '@/api';
import { ref, reactive, onMounted, watch } from 'vue';
import type { IPage } from '@interfaces/i-common';

interface Props {
  params?: any;
  requestName?: string;
  folderName?: string;
  isdefineParams?: boolean;
  isPadding?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
  params: {},
  requestName: '',
  folderName: '',
  // 是否进入页面需要改变params参数
  isdefineParams: false,
  isPadding: true
});
const emits = defineEmits(['getData']);

// 加载中状态
const loading = ref<boolean>(false);
// 加载完成状态
const finished = ref<boolean>(false);
// 加载失败状态
const loadError = ref<boolean>(false);
// 自定义参数
let defineParams = reactive<IPage>({
  currPage: 1,
  pageSize: 10
});
// 数据加载状态提示文字
const loadText = reactive<Record<string, string>>({
  loadingText: '加载中...',
  finishedText: '',
  errorText: '请求失败，点击重新加载',
  noData: '暂无数据',
  noMore: '没有更多了'
});

// 查询列表数据
const getApiGeekList = async () => {
  try {
    loadText.finishedText = '';
    finished.value = true;
    // 统一使用全局接口处的加载状态样式
    loading.value = false;
    const { success, data, page } = await api[props.folderName][props.requestName]({
      ...defineParams
    });
    if (success) {
      finished.value = false;
      emits('getData', data, defineParams.currPage, page?.recordCount);

      // 判断是否无数据
      if (defineParams.currPage >= page.pageTotal || !page.pageTotal) {
        finished.value = true;
        loadText.finishedText = !page.pageTotal ? loadText.noData : loadText.noMore;
        return;
      }
    } else {
      loadError.value = true;
      defineParams.currPage = defineParams.currPage > 1 ? defineParams.currPage - 1 : 1;
    }
  } catch (error) {
    loadError.value = true;
    defineParams.currPage = defineParams.currPage > 1 ? defineParams.currPage - 1 : 1;
  }
  loading.value = false;
};

// 监听参数参数是否改变
watch(
  () => props.params,
  () => {
    defineParams = Object.assign(defineParams, props.params);
    defineParams.currPage = 1;
    getApiGeekList();
  },
  {
    deep: true
  }
);

// 触底查询
const onLoad = () => {
  defineParams.currPage += 1;
  getApiGeekList();
};

// 重新查询第一页数据
const queryFirstPage = () => {
  defineParams.currPage = 1;
  getApiGeekList();
};

// 默认查询
onMounted(() => {
  defineParams = Object.assign(defineParams, props.params);
  if (!props.isdefineParams) {
    getApiGeekList();
  }
});

// 暴露queryFirstPage方法，用于重新查询数据
defineExpose({
  queryFirstPage
});
</script>

<style lang="scss" scoped>
.geek-list {
  padding: 10px 40px;

  &.no-padding {
    padding: 0;
  }
}
</style>
